/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "Manager.h"
#include "DataSourceWaveFile.h"

#ifdef WIN_VERSION
#include "DataSourceXM.h"
#include "MP3File.h"
#endif

#include "ImmortalChannel.h"
#include <AutoContainer.h>
#include <list>

namespace liba
{
namespace noise
{

typedef AutoContainer< std::list<hard::Channel *> > ImmortalChannels;
ImmortalChannels * immortal_channels;

Manager::Creator::Creator()
{
	if( immortal_channels )
		THROW(Gluck(__FUNCTION__, "immortal_channels already exists" ));
	immortal_channels = new ImmortalChannels;
}

Manager::Creator::~Creator()
{
	delete immortal_channels; immortal_channels = 0;
}

void Manager::Creator::life_cycle(double delta_time)
{
	Manager::update_immortal_channels();
}

hard::Hardware * Manager::get_hardware()
{
	if( get_hardwares().empty() )
		THROW(Gluck(__FUNCTION__, "get_hardwares().empty()"));
	return get_hardwares().back();
}

DataSource * Manager::create_datasource(const filesystem::String & name)
{
	DataSourceWaveFile * ds_wav = new DataSourceWaveFile( name );
	if( ds_wav->is_valid() )
		return ds_wav;
	delete ds_wav; ds_wav = 0;

#ifdef WIN_VERSION
	MP3File * ds_mp3 = new MP3File( name );
	if( ds_mp3->is_valid() )
		return ds_mp3;
	delete ds_mp3; ds_mp3 = 0;

	DataSourceXM * ds_xm = new DataSourceXM( name );
	if( ds_xm->is_valid() )
		return ds_xm;
	delete ds_xm; ds_xm = 0;
#endif

	return 0;
}

hard::Channel * Manager::create_immortal_static_channel( const Atom & channel_type, const filesystem::String & name)
{
	if( get_hardwares().empty() )
		THROW(Gluck(__FUNCTION__, "get_hardwares().empty()"));
	return new ImmortalChannel( get_hardware()->create_static_channel( channel_type, name ) );
}

hard::Channel * Manager::create_immortal_streaming_channel( const Atom & channel_type)
{
	if( get_hardwares().empty() )
		THROW(Gluck(__FUNCTION__, "get_hardwares().empty()"));
	return new ImmortalChannel( get_hardware()->create_streaming_channel( channel_type ) );
}

/*hard::Channel * Manager::create_immortal_channel(const Atom & channel_type)
{
	if( get_hardwares().empty() )
		throw Gluck(__FUNCTION__, "get_hardwares().empty()");
	return new ImmortalChannel( get_hardware()->create_channel( channel_type ) );
}

hard::Channel * Manager::create_immortal_channel(const Atom & channel_type, double length_sec)
{
	if( get_hardwares().empty() )
		throw Gluck(__FUNCTION__, "get_hardwares().empty()");
	return new ImmortalChannel( get_hardware()->create_channel( channel_type, length_sec ) );
}*/

void Manager::make_immortal(hard::Channel * channel)
{
///	logs::log() << "Manager::make_immortal\n";
	if( immortal_channels )
		immortal_channels->push_back( channel );
	else
	{
		delete channel; channel = 0;
	}
}

void Manager::update_immortal_channels()
{
	ImmortalChannels::iterator it = immortal_channels->begin();
	while( it != immortal_channels->end() )
		if( (*it)->is_finished() )
		{
///			logs::log() << (int)(*it) << "Manager::update_immortal_channels - channel deleted\n";
			delete (*it);
			it = immortal_channels->erase( it );
		}
		else
			++it;
}

} // namespace noise
} // namesapce liba

